#include <mbed.h>
#include "baidu_mbed_soc_wrapper.h"
#include "baidu_http_client_c.h"
#include "baidu_http_client_log.h"

//#define BAIDU_HTTP_CLIENT_TEST_URL "http://yinyueshiting.baidu.com/data2/music/fcb085c9d1553a21d8a858a359a8b886/274961849/274961734252000128.mp3?xcode=ce8a4c9c910e6be5f5d44a3a1acfff98"
//#define BAIDU_HTTP_CLIENT_TEST_URL  "http://mqtt.org/"
#define BAIDU_HTTP_CLIENT_TEST_URL "http://mp3.9ku.com/mp3/539/538635.mp3"
//#define BAIDU_HTTP_CLIENT_TEST_URL  "http://114.80.155.175/mp3.9ku.com/mp3/539/538635.mp3"


//#define BAIDU_HTTP_CLIENT_TEST_URL "http://yinyueshiting.baidu.com/data2/music/aed7f2e0dededee40a131b5d41d004dc/106184008/1061255821480021261128.mp3?xcode=e918110c9df7bacab4504f1dc3711450"

#ifdef SPEED_TEST
static mbed::Timer g_hctest_timer;
static unsigned int g_n_hctest_mp3_data_total = 0;
static int g_hctest_start_time = 0;
static int g_hctest_time_total = 0;
#endif

static FILE *p_mp3_file = NULL;

static bool needStop = false;

int http_client_mp3_data_out_handler(void *p_user_ctx, e_data_pos pos, char *buf, size_t len, char *type)
{	
    (void)p_user_ctx;

#ifdef SPEED_TEST
    g_n_hctest_mp3_data_total += len;

    if ((pos & DATA_FIRST) == DATA_FIRST){
        g_hctest_start_time = g_hctest_timer.read_ms();
    }

    if ((pos & DATA_MID) == DATA_MID){
        if (g_hctest_timer.read_ms() - g_hctest_start_time > g_hctest_time_total + 800){ //org = 1000(1s), change to 800ms
            g_hctest_time_total = g_hctest_timer.read_ms() - g_hctest_start_time;
            printf("Http client reading %d bytes data costs %d ms(speed:%f Kb/s)\n", \
                g_n_hctest_mp3_data_total, g_hctest_time_total, 1.0 * g_n_hctest_mp3_data_total * 1000 * 8 / g_hctest_time_total / 1024);

            g_n_hctest_mp3_data_total = 0;
            g_hctest_time_total = 0;
            g_hctest_start_time = g_hctest_timer.read_ms();
        }

    }

    if ((pos & DATA_LAST) == DATA_LAST){
       g_hctest_time_total = g_hctest_timer.read_ms() - g_hctest_start_time;
       printf("Ending: Http client reading %d bytes data costs %d ms(speed:%f Kb/s)\n", \
            g_n_hctest_mp3_data_total, g_hctest_time_total, 1.0 * g_n_hctest_mp3_data_total * 1000 * 8 / g_hctest_time_total / 1024);
    }
#endif

#if 1
    if ((pos & DATA_FIRST) == DATA_FIRST){
        p_mp3_file = fopen("/sd/data_output.html", "w");
        if (!p_mp3_file){
            HCLOGE("open file failed!\n");
            return -1;
        }
    }

    if (buf && len && p_mp3_file){
        fwrite(buf, 1, len, p_mp3_file);
    }

    if ((pos & DATA_LAST) == DATA_LAST){
        if (p_mp3_file){
            fclose(p_mp3_file);
            p_mp3_file = NULL;
        }
    }
#else
    if (buf && len){
        buf[len] = '\0';
        printf("%s", buf);
    }
#endif    
    return 0;
}

int http_client_check_need_stop()
{
    return needStop;
}

void http_client_reset_stop_flag()
{
    needStop = false;
}

void http_client_c_test(void const *argument)
{
    int ret = 0;
    http_client_c client_inst;
    socket_ops ops = {0, 
        mbed_socket_init, 
        mbed_socket_open,
        mbed_socket_connect, 
        mbed_socket_set_blocking,
        mbed_socket_set_timeout,
        mbed_socket_recv,
        mbed_socket_send,
        mbed_socket_close,
        mbed_socket_destroy
        };

#ifdef SPEED_TEST
    g_hctest_timer.start();
#endif

    while (true) {
        http_client_init(&client_inst);
        if (http_client_init_socket_ops(&client_inst, &ops, NULL) != HTTP_OK){
            return;
        }

        http_client_reg_data_hdlr_cb(&client_inst, http_client_mp3_data_out_handler, NULL);
        http_client_reg_stop_notify_cb(&client_inst, http_client_check_need_stop, http_client_reset_stop_flag);

        ret = http_client_get(&client_inst, BAIDU_HTTP_CLIENT_TEST_URL, 0);
        printf("http get return:%d\n", ret);

        http_client_destroy(&client_inst);

        Thread::wait(osWaitForever);
    }
}

#include "mbed.h"
int main()
{
    Thread thread(http_client_c_test, NULL, osPriorityAboveNormal, 10*1024);

#ifdef SPEED_TEST
    while (true) {
        Thread::wait(10000);
        needStop = true;
    }
#else
    Thread::wait(osWaitForever);
#endif
}

